﻿using System.Collections.Generic;
using System.Linq;
using Dgg.Anug.Cqrs.Core.Domain.Admin.Events;
using Dgg.Anug.Cqrs.Core.Infrastructure.Data;
using Dgg.Anug.Cqrs.Core.Infrastructure.Eventing;
using Raven.Client;

namespace Dgg.Anug.Cqrs.Core.Application.DefectHandling.Services.Handlers
{
	public class SolutionCreatedSnapshotCreator : IHandler<SolutionCreated>
	{
		private readonly ISnapshotSession _snapshotSession;

		public SolutionCreatedSnapshotCreator(ISnapshotSession snapshotSession)
		{
			_snapshotSession = snapshotSession;
		}

		public bool Handle(SolutionCreated e)
		{
			Domain.DefectHandling.Solution ds = new Domain.DefectHandling.Solution(e.ReceiverId, e.Name);
			_snapshotSession.Save(ds);
			return true;
		}
	}

	public class SolutionCreatedEntitiesQueryUpdater : IHandler<SolutionCreated>
	{
		private readonly IDocumentSession _modelSession;

		public SolutionCreatedEntitiesQueryUpdater(IDocumentSession modelSession)
		{
			_modelSession = modelSession;
		}

		public bool Handle(SolutionCreated e)
		{
			if (!documentExists())
			{
				createSupportEntitiesFor(e);
			}
			else
			{
				updateSupportEntitiesFor(e);
			}
			return true;
		}

		private bool documentExists()
		{
			return _modelSession.LuceneQuery<Presentation.Models.DefectHandling.SupportEntities>().Any();
		}

		private void createSupportEntitiesFor(SolutionCreated e)
		{
			_modelSession.Store(Presentation.Models.DefectHandling.SupportEntities.FirstWith(
				new Presentation.Models.DefectHandling.Solution { Id = e.ReceiverId.ToString(), Name = e.Name }));
		}

		private void updateSupportEntitiesFor(SolutionCreated e)
		{
			// should work, but does not
			/*_modelSession.DatabaseCommands.Batch(
				new[]
				{
					new PatchCommandData
					{
						Key = "SupportEntities/0",
						Patches = new[]
						{
							new PatchRequest
							{
								Type = "Add",
								Name = "Solution",
								Value = JObject.FromObject(new Presentation.Models.DefectHandling.Solution
								{
									Id = solution.Id.ToString(),
									Name = solution.Name
								})
							}
						}
					}
				});*/

			// is not optimal to get the whole document for adding to an internal array, but...
			var entities = _modelSession.Single<Presentation.Models.DefectHandling.SupportEntities>(
				Presentation.Models.DefectHandling.SupportEntities.TheId);
			var solutions = entities.Solutions ?? new List<Presentation.Models.DefectHandling.Solution>();
			solutions.Add(new Presentation.Models.DefectHandling.Solution
			{
				Id = e.ReceiverId.ToString(),
				Name = e.Name
			});
			entities.Solutions = solutions;
		}
	}
}
